package com.example.occlusiondemo.activity;

import static com.example.occlusiondemo.PathConfig.HEIGHT;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.os.Bundle;
import android.view.Surface;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.eqgis.eqtool.tmp.Utils;
import com.eqgis.eqtool.tmp.VibrateHelper;
import com.example.occlusiondemo.DataManager;
import com.example.occlusiondemo.Log;
import com.example.occlusiondemo.MarkerConfig;
import com.example.occlusiondemo.PathConfig;
import com.example.occlusiondemo.R;
import com.example.occlusiondemo.ScreenPointManager;
import com.example.occlusiondemo.animation.ViewAnimation;
import com.example.occlusiondemo.layout.LayoutUtils;
import com.example.occlusiondemo.view.DynamicView;
import com.example.occlusiondemo.layout.MainLayout;
import com.example.occlusiondemo.layout.MainLayoutCallback;
import com.example.occlusiondemo.layout.func.ExcavatorManager;
import com.google.android.filament.MaterialInstance;
import com.google.are.sceneform.ARPlatForm;
import com.google.are.sceneform.AnchorNode;
import com.google.are.sceneform.collision.Box;
import com.google.are.sceneform.math.Quaternion;
import com.google.are.sceneform.math.Vector3;
import com.google.are.sceneform.rendering.ExternalTexture;
import com.google.are.sceneform.rendering.Material;
import com.google.are.sceneform.rendering.RenderableInstance;
import com.supermap.ar.Point3D;
import com.supermap.ar.areffect.AREffectElement;
import com.supermap.ar.areffect.AREffectView;
import com.supermap.ar.areffect.ConvertTool;
import com.supermap.ar.areffect.Location;
import com.supermap.ar.areffect.OcclusionHelper;
import com.supermap.ar.areffect.TouchResult;
import com.supermap.ar.areffect.config.ResourceUtil;
import com.supermap.ar.areffect.excavator.PitMarkerLayer;
import com.supermap.ar.areffect.preset.ARGeoPrism;
import com.supermap.data.Environment;
import com.supermap.hiar.ARCamera;
import com.supermap.hiar.AREngine;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import java.util.function.Function;

public class PipeActivity extends Activity{
    private AREffectView arView;
    private MainLayout mainLayout;
    private OcclusionHelper occlusionHelper;
    private DynamicView dynamicView;

    static List<Point3D> SRC = Arrays.asList(
//            new Point3D(-1, -1, /*地面高度为0，*/0.0f),
//            new Point3D(-1, 30, 0.0f),
//            new Point3D(30, 30, 0.0f),
//            new Point3D(30, -1, 0.0f),
//            new Point3D(-1, -1, 0.0f)
            new Point3D(1.8f, 7.8f, /*地面高度为0，*/0.0f),
            new Point3D(1.8f, -4.2f, 0.0f),
            new Point3D(-5.4f, -4.2f, 0.0f),
            new Point3D(-5.4f, 7.8f, 0.0f),
            new Point3D(1.8f, 7.8f, 0.0f)
    );
    static List<Location> ROOM_BOUNDS = new ArrayList<>();

    private ArrayList<int[]> screenPointNone = new ArrayList<>();
    private ARGeoPrism roomBox;

    @Override
    protected void onDestroy() {
        arView.onDestroy();
        super.onDestroy();
        finish();
        android.os.Process.killProcess(android.os.Process.myPid());
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Utils.hideBottomUIMenu(this);
        Utils.hideTopUI(this);
        //设置许可
        Environment.setLicensePath(PathConfig.LICENSE_PATH);
        Environment.initialization(/*上下文*/this,/*是否是64位*/true);
        setContentView(R.layout.activity_main);

        //<editor-fold> -
        //计算房间的经纬度 & 默认值
        for (int i = 0; i < SRC.size(); i++) {
            Location location = ConvertTool.convertToLocation(SRC.get(i), MarkerConfig.REF_LOCATION,0);
            ROOM_BOUNDS.add(location);
        }
        screenPointNone.add(new int[]{0,0});
        screenPointNone.add(new int[]{0,0});
        screenPointNone.add(new int[]{0,0});

        //</editor-fold>

        arView = findViewById(R.id.ar_view);

        dynamicView = findViewById(R.id.test_view);
        dynamicView.connectView(arView);

//        arView.setVisibleDistance(100);
        //禁用光源，防止出现阴影
        arView.getArSceneView().getScene().getSunlight().setEnabled(false);
        arView.setPlaneVisible(false);
//        arView.addOnUpdateListener(this);
        ScreenPointManager.getInstance().setOnUpdatePointListener(new ScreenPointManager.OnUpdatePointListener() {
            @Override
            public void update(List<ArrayList<int[]>> screenPoint,List<ArrayList<int[]>> bottomScreenPoint) {
                //每次点更新时，刷新
                if (occlusionHelper.isEnabled()){
                    if (mainLayout.getMode() == MainLayout.Mode.VIEWPORT){
                            //根据最新的产品要求， 此处轮廓线的显示由按钮开关控制了。2022年10月24日
//                    if (mainLayout.getMode() == MainLayout.Mode.VIEWPORT && Status.editedParameter){
//                        dynamicView.updateLine(screenPoint,bottomScreenPoint);
                        //仅当视口模式的编辑状态才更新
                        //屏幕层绘制裁剪范围框&标注callOut
                        DynamicView dynamicView = PipeActivity.this.dynamicView.setPoints(screenPoint.get(0));
                        if (LayoutUtils.getClickStatus(R.id.icon_tool_outline)){
//                            dynamicView.updateLine(screenPoint.get(0),bottomScreenPoint.get(0));
                            //更新标注
                            synchronized (DynamicView.class){
                                //更新标注
                                Canvas canvas = dynamicView.getHolder().lockCanvas();
                                canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
                                //绘制
                                ExcavatorManager.getInstance().getPitMarkerLayer().drawMarker(canvas);
                                dynamicView.getHolder().unlockCanvasAndPost(canvas);
                            }
                        }
                    }
//                    if (Status.editedParameter){
//                        //不显示，范围0
//                        occlusionHelper.setUniquePointList(screenPointNone).refresh();
//                    }else {
//                        //备注：当处于修改开挖参数的时候，不刷新裁剪范围
//                        //desc-执行画面裁剪
//                        if (screenPoint!=null){
//                            //刷新裁剪范围
//                            occlusionHelper.setUniquePointList(screenPoint).refresh();
//                        }
//                    }
                    if (screenPoint!=null){
                        //刷新裁剪范围
                        occlusionHelper.clearPointList();
                        for (int i = 0; i < screenPoint.size(); i++) {
                            occlusionHelper.addPointList(screenPoint.get(i));
                        }
                        occlusionHelper.refresh();
                    }
                }
            }
        });

        //遮挡管理器
        occlusionHelper = arView.getOcclusionHelper();
        occlusionHelper.init(0.5f).setRenderMode(OcclusionHelper.RenderMode.NORMAL);
        occlusionHelper.setEnabled(true);

        initUI();
    }

    @Override
    protected void onResume() {
        arView.onResume();
        super.onResume();
        if (StartActivity.isDebug){
            Toast.makeText(this, "AR:"+ ARPlatForm.getEngineType() + " " + AREngine.isUsingAREngine() +" "
                    + ARCamera.getOffsetAngle(), Toast.LENGTH_SHORT).show();
        }
    }

    private void initUI() {
        if (mainLayout != null)return;
        mainLayout = findViewById(R.id.main_layout);
        try {
            mainLayout.initView(arView);
        }catch (IllegalArgumentException e){
            Toast.makeText(this, "图片数据库加载失败，请重启！", Toast.LENGTH_SHORT).show();
            return;
        }
        mainLayout.setMainLayoutCallback(new MainLayoutCallback() {
            @Override
            public void calibrateDeviceInfo(Location location, float azimuth) {
                //校准相机的启动位置和方位角
                if (StartActivity.isDebug){
                    Toast.makeText(PipeActivity.this, "angle:" + azimuth, Toast.LENGTH_SHORT).show();
                }
                arView.setAzimuth(azimuth);
                arView.setDeviceLocation(location);
                loadData();
            }

            @SuppressLint("ClickableViewAccessibility")
            @Override
            public void changeMode(MainLayout.Mode currentMode) {
                //desc-切换模式时，关闭属性框
                findViewById(R.id.pipe_attr).setVisibility(View.GONE);
                //取消管线的选中渲染状态
                DataManager.getInstance().unSelectAll();

                switch (currentMode){
                    case VIEWPORT:
                        //添加上视口模式修改参数的手势
                        dynamicView.setOnTouchListener(dynamicView);
                        break;
                    case ROLLING:
                    case NULL:
                        //置空手势监听
                        dynamicView.setOnTouchListener(null);
                        dynamicView.clear();
                        break;
                }
            }

            @Override
            public void setRoomBoxVisibility(boolean visibility) {
                if (roomBox != null){
                    roomBox.getParentElement().setVisiblity(visibility);
                }
            }
        });

        //设置数据点击事件 //TODO 取消属性查询 //点击查询修改管线模型纹理
        ExternalTexture externalTexture = new ExternalTexture();
        externalTexture.getSurfaceTexture().setDefaultBufferSize(100,100);
        Surface surface = externalTexture.getSurface();
        Canvas canvas = surface.lockHardwareCanvas();
        canvas.drawColor(Color.BLUE);
        surface.unlockCanvasAndPost(canvas);

        /**
         * 确认模型材质
         * 修改模型mat
         */
        HashMap<AREffectElement, Material> elementMaterialHashMap = new HashMap<>();
        DataManager.getInstance().setDataManagerCallback(new DataManager.DataManagerCallback() {
            @Override
            public void onClick(AREffectElement element, TouchResult touchResult) {
                Box box = (Box) element.getAnchorNode().getCollisionShape();
                Vector3 size = box.getSize();
                Vector3 offset = box.getCenter();
                @SuppressLint("DefaultLocale")
                String offsetStr = "["+String.format("%.1f",offset.x) +","+ String.format("%.1f",offset.y)  +","+ String.format("%.1f",offset.z)+"]";
                float minSize = Math.min(Math.min(size.x,size.y),size.z);
                String diameterStr = String.format("%.2f",minSize) + "米";

                //这是第一版属性框
//                TextView pipeAttrValue = findViewById(R.id.pipe_info_value);
//                pipeAttrValue.setText(element.getElementName()+"\n新构造\n"+minSize+"\nGB/T 19928\n常规\n未知\n"+offsetStr);
                //第二版属性框
                ((TextView)findViewById(R.id.attr_id)).setText(element.getElementName());
                ((TextView)findViewById(R.id.attr_diameter)).setText(diameterStr);
                ((TextView)findViewById(R.id.attr_offset)).setText(offsetStr);

                //开启属性框
                View view = findViewById(R.id.pipe_attr);
                view.setVisibility(View.VISIBLE);
                ViewAnimation.viewExpandClick(view,500);

//                //材质修改
////                AnchorNode anchorNode = element.getAnchorNode();
////                Renderable renderable = anchorNode.getRenderable();
////                Material material = anchorNode.getRenderableInstance().getMaterial(0);
////                FilamentAsset asset = anchorNode.getRenderableInstance().getFilamentAsset();
////                material.materialData.getFilamentMaterial().getParameters()
//                AnchorNode anchorNode = element.getAnchorNode();
//                Material material = anchorNode.getRenderableInstance().getMaterial(0);
//                elementMaterialHashMap.put(element,material);
//
//                Material mkCp = material.clone();
////                MaterialInstance materialInstance = material.getFilamentMaterialInstance();
////                MaterialInternalData materialData = new MaterialInternalDataGltfImpl(materialInstance.getMaterial());
////                Material mkCp = new Material(materialData);
////                mkCp.updateGltfMaterialInstance(materialInstance);
//
////                mkCp.setFloat4("baseColorFactor", new Color(1,1,1,1));
//
////                material.setFloat4("baseColorFactor",0,1,0,1);
//                material.setFloat4("emissiveFactor",0,1,0,0.8f);
////                mkCp.getFilamentMaterialInstance().setParameter("baseColorFactor",1,1,0,1);
////                mkCp.getFilamentMaterialInstance().setParameter("emissive",1,0,0,0.5f);
////                RenderableInstance renderableInstance = anchorNode.getRenderableInstance();
////                if (material.getFilamentMaterialInstance().getMaterial().hasParameter("baseColorFactor")){
//
////                    renderableInstance.setMaterial(0,mkCp);
////                    renderableInstance.setMaterial(0,material);
////                    selectedMat.setFloat4("baseColorFactor",1,1,1,1);
////                    renderableInstance.setMaterial(0,selectedMat);
//
////                    com.google.android.filament.Material fMat = anchorNode.getRenderableInstance().getMaterial(0).getFilamentMaterialInstance().getMaterial();
////                    MaterialInstance select = MaterialInstance.duplicate(fMat.getDefaultInstance(), "select");
////                    anchorNode.getRenderableInstance().setMaterial(0,selectedMat);
////                    renderableInstance.getMaterial(0).setFloat4("baseColorFactor",);
////                }
//                final int materialMat = ResourceUtil.getRawId(getApplicationContext(), "external_chroma_key_video_material");;
////        int materialMat = ResourceConfig.getInstance(getContext()).getVideoMaterialKey();
//                CompletableFuture<Material> build = Material.builder().setSource(getApplicationContext(),materialMat).build();
//                build.thenAccept(new Consumer<Material>() {
//                    @Override
//                    public void accept(Material mat) {
//                        mat.setExternalTexture("videoTexture", externalTexture);
//                        mat.setFloat4("keyColor", new com.google.are.sceneform.rendering.Color(0,0,0,0));
//                        anchorNode.getRenderableInstance().setMaterial(0,mat);
//                    }
//                }).exceptionally(new Function<Throwable, Void>() {
//                    @Override
//                    public Void apply(Throwable throwable) {
//                        throw new IllegalStateException(throwable.getMessage());
//                    }
//                });

            }
        });

        //View closeAttrBtn
        findViewById(/*属性框关闭按钮*/R.id.icon_other_close).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                VibrateHelper.vSimple(getApplicationContext(),75);
                //desc-关闭属性框
                findViewById(R.id.pipe_attr).setVisibility(View.GONE);
            }
        });

    }

    /**
     * 数据加载
     */
    private void loadData() {
        //模型加载的节点
        AREffectElement d = new AREffectElement(getBaseContext());
        d.setParentNode(arView);
        Point3D basePosition = ConvertTool.convertToArPosition(arView, /*采用marker的位置*/MarkerConfig.REF_LOCATION);
        d.setPosition(basePosition);
        d.setRotationQuaternion(new Quaternion(Vector3.up(),arView.getAzimuth()));
        if (StartActivity.isDebug){
            Log.d(PipeActivity.class.getSimpleName(),"位置："+basePosition.toString());
        }

        List<Point3D> roomBounds = new ArrayList<>();
        for (int i = 0; i < ROOM_BOUNDS.size(); i++) {
            roomBounds.add(ConvertTool.convertToArPosition(arView,ROOM_BOUNDS.get(i)));
        }
        //“检测墙”，注意在此之前，需确保相机启动时的方位角、位置已更新
        ARGeoPrism geoVerticalRegion = new ARGeoPrism();
        geoVerticalRegion.setParentNode(arView);
        geoVerticalRegion.setRenderable(false);//不渲染出来，仅用作碰撞计算
//        geoVerticalRegion.setColor(1.0f,1.0f,1.0f,0.2f);
        geoVerticalRegion.addPart(roomBounds,/*房间层高*/HEIGHT);
        //区域包围盒
        roomBox = geoVerticalRegion;

        ExcavatorManager.getInstance().init(geoVerticalRegion);

        //<editor-fold> - 加载管线 //todo 数据已替换
        AREffectElement a = new AREffectElement(getBaseContext());
        a.setParentNode(d);
//        a.getAnchorNode().setLocalRotation((new Quaternion(Vector3.down(),-90)));
//        a.getAnchorNode().setLocalRotation((new Quaternion(Vector3.down(),90)));//新数据不用
//        a.setRelativePosition(new Point3D(3,4,0));
        DataManager.getInstance().addPipeScene(a,PathConfig.UNDERGROUND_PIPE_DATA,true, DataManager.Type.UNDERGROUND);

        AREffectElement b = new AREffectElement(getBaseContext());
        b.setParentNode(d);
//        b.getAnchorNode().setLocalRotation((new Quaternion(Vector3.down(),90)));//新数据不用
//        b.getAnchorNode().setLocalRotation((new Quaternion(Vector3.down(),-90)));
//        b.setRelativePosition(new Point3D(-5.6f,2,1.2f));
        DataManager.getInstance().addPipeScene(b,PathConfig.VERTICAL_PIPE_DATA,/*启用点击事件*/true,DataManager.Type.WALL);

//        AREffectElement b = new AREffectElement(getBaseContext());
//        b.setParentNode(d);
//        b.setRelativePosition(new Point3D(4,6.5f,-0.8f));
//        DataManager.getInstance().addPipeScene(b,PathConfig.VERTICAL_PIPE_DATA);

        AREffectElement c = new AREffectElement(getBaseContext());
        c.setParentNode(d);
//        c.getAnchorNode().setLocalRotation((new Quaternion(Vector3.down(),90)));//新数据不用
//        c.setRelativePosition(new Point3D(-2,2,2.2f));
        DataManager.getInstance().addPipeScene(c,PathConfig.TOP_PIPE_DATA,true,DataManager.Type.CEILING);
        //</editor-fold>
    }

    /**
     * 布局控件显示隐藏
     * @param view
     */
    public void changeLayout(View view) {
        VibrateHelper.vSimple(this,75);
        if (mainLayout!=null){
            if (mainLayout.getVisibility() == View.VISIBLE){
                ((ImageView)view).setImageDrawable(getDrawable(R.drawable.change_max));
                ViewAnimation.viewMove1(mainLayout);
                view.getHandler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        //若显示，则需隐藏
                        mainLayout.setVisibility(View.GONE);
                    }
                },200);
            }else {
                mainLayout.setVisibility(View.VISIBLE);
                ((ImageView)view).setImageDrawable(getDrawable(R.drawable.change_min));
                ViewAnimation.viewMove2(mainLayout);
            }
        }
        ViewAnimation.viewExpandClick2(view,200);
    }
}
